package com.swallow.auth.common.utils;


import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.ToNumberPolicy;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author 18310740596@163.com
 * @date 2023-06-25 08:59:52
 * @describe json工具类
 */
public class GsonUtil {

    private static final Gson GSON;

    static {
        // 创建json实例
        GSON = new GsonBuilder()
                //序列化null
                .serializeNulls()
                .setNumberToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
                .setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
                // 设置日期时间格式，另有2个重载方法
                // 在序列化和反序化时均生效
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                // 禁此序列化内部类
                .disableInnerClassSerialization()
                //禁止转义html标签
                .disableHtmlEscaping()
                .create();
    }

    /**
     *  序列化为Json String
     *
     * @param obj 序列化对象
     * @param <T>
     * @return 序列化结果
     */
    public static<T> String toJson(T obj) {
        return GSON.toJson(obj);
    }

    /**
     *  解析为Object 对象
     *
     * @param json 反序列化json入参
     * @param <T>
     * @return 反序列化对象
     */
    public static <T> T parseObject(String json) {
        return parseObject(json, new TypeToken<Object>(){}.getType());
    }

    /**
     *  parse json to map
     *
     * @param json
     * @param <K>
     * @param <V>
     * @return
     */
    public static<K,V> Map<K, V> json2Map(String json) {
        return parseObject(json, new TypeToken<Map<K, V>>(){});
    }

    /**
     *  对象转换为Map
     *
     * @param obj 转对象
     * @return    转换结果
     * @param <T> 转换实体类型
     * @param <K> map的key值
     * @param <V> map的value值
     */
    public static <T, K, V> Map<K, V> obj2Map(T obj) {
        if(obj == null){
            return Collections.emptyMap();
        }
        return json2Map(GSON.toJson(obj));
    }

    /**
     *  解析为Object 对象
     *
     * @param json 反序列化入参
     * @param clazz 反序列化后的class对象
     * @param <T>
     * @return 反序列化结果
     */
    public static <T> T parseObject(String json, Class<T> clazz) {
        return GSON.fromJson(json, clazz);
    }

    /**
     *  解析为Object 对象
     *
     *  eg:
     *   String json = [{
     *       "name": "zs",
     *       "age": 20
     *   }
     *
     *   List<User> user = GsonUtils.parseObject(json, new TypeToken<List<User>(){});
     *
     *
     * @param json 反序列化入参
     * @param typeToken 反序列化后的对象类型
     * @param <T>
     * @return 反序列化结果
     */
    public static <T> T parseObject(String json, TypeToken<T> typeToken) {
        return parseObject(json, typeToken.getType());
    }


    /**
     *  解析为Object 对象
     *
     *  eg:
     * String json = [{
     *            "name": "zs",
     *            "age": 20
     *         }
     *
     *  List<User> user = GsonUtils.parseObject(json, new TypeToken<List<User>(){}.getType());
     *
     * @param json 反序列化入参
     * @param type 反序列化后的对象类型
     * @param <T>
     * @return 反序列化结果
     */
    public static <T> T parseObject(String json, Type type) {
        return GSON.fromJson(json, type);
    }


    /**
     *  将请求参数转换为list集合
     *
     * @param json    请求json串
     * @param clazz   需要转换的类型
     * @param <T>     具体类型
     * @return        转换后的参数
     */
    public static <T> List<T> parse2List(String json, Class<T> clazz) {
        final Type type = new ParameterizedTypeImpl(clazz);
        return GSON.fromJson(json, type);
    }
}


class ParameterizedTypeImpl implements ParameterizedType {
    Class<?> clazz;

    public ParameterizedTypeImpl(Class<?> clz) {
        clazz = clz;
    }

    @Override
    public Type[] getActualTypeArguments() {
        return new Type[]{clazz};
    }

    @Override
    public Type getRawType() {
        return List.class;
    }

    @Override
    public Type getOwnerType() {
        return null;
    }
}
